/*            Copyright(c) 2006-2008 Dave Sexton           *
 * http://www.codeplex.com/DocProject                      *
 * http://www.codeplex.com/DocProject/Project/License.aspx *
 ***********************************************************/
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.IO;
using DaveSexton.DocProject.Resources;

namespace DaveSexton.DocProject.Engine
{
	public class CopyDirectoryBuildStep<TEngine> : BuildStep<TEngine>
		where TEngine : IBuildEngine
	{
		#region Public Properties
		public override string Name
		{
			get
			{
				return "Copy Directory";
			}
		}

		public DirectoryCopier Copier
		{
			get
			{
				return copier;
			}
		}

		public bool DeleteSourceAfterCopy
		{
			get
			{
				return copier.DeleteSource;
			}
			set
			{
				copier.DeleteSource = value;
			}
		}

		public string Source
		{
			get
			{
				return source;
			}
		}

		public string Target
		{
			get
			{
				return target;
			}
		}
		#endregion

		#region Private / Protected
		private readonly string source, target;
		private readonly DirectoryCopier copier = new DirectoryCopier();
		#endregion

		#region Constructors
		/// <summary>
		/// Constructs a new instance of the <see cref="CopyDirectoryBuildStep" /> class.
		/// </summary>
		public CopyDirectoryBuildStep(TEngine engine, string source, string target)
			: this(engine, false, source, target, false)
		{
		}

		/// <summary>
		/// Constructs a new instance of the <see cref="CopyDirectoryBuildStep" /> class.
		/// </summary>
		public CopyDirectoryBuildStep(TEngine engine, bool continueOnError, string source, string target)
			: this(engine, continueOnError, source, target, false)
		{
		}

		/// <summary>
		/// Constructs a new instance of the <see cref="CopyDirectoryBuildStep" /> class.
		/// </summary>
		public CopyDirectoryBuildStep(TEngine engine, string source, string target, bool deleteSource)
			: this(engine, false, source, target, deleteSource)
		{
		}

		/// <summary>
		/// Constructs a new instance of the <see cref="CopyDirectoryBuildStep" /> class.
		/// </summary>
		public CopyDirectoryBuildStep(TEngine engine, bool continueOnError, string source, string target, bool deleteSource)
			: base(engine)
		{
			if (string.IsNullOrEmpty(source))
				throw new ArgumentException(Errors.NullOrEmpty, "source");

			if (string.IsNullOrEmpty(target))
				throw new ArgumentException(Errors.NullOrEmpty, "target");

			this.source = source;
			this.target = target;

			ContinueOnError = continueOnError;

			copier.DeleteSource = deleteSource;
		}

		/// <summary>
		/// Constructs a new instance of the <see cref="CopyDirectoryBuildStep" /> class.
		/// </summary>
		public CopyDirectoryBuildStep(TEngine engine, string source, string target, string filePattern)
			: this(engine, false, source, target, false, filePattern)
		{
		}

		/// <summary>
		/// Constructs a new instance of the <see cref="CopyDirectoryBuildStep" /> class.
		/// </summary>
		public CopyDirectoryBuildStep(TEngine engine, bool continueOnError, string source, string target, string filePattern)
			: this(engine, continueOnError, source, target, false, filePattern)
		{
		}

		/// <summary>
		/// Constructs a new instance of the <see cref="CopyDirectoryBuildStep" /> class.
		/// </summary>
		public CopyDirectoryBuildStep(TEngine engine, string source, string target, bool deleteSource, string filePattern)
			: this(engine, false, source, target, deleteSource, filePattern)
		{
		}

		/// <summary>
		/// Constructs a new instance of the <see cref="CopyDirectoryBuildStep" /> class.
		/// </summary>
		public CopyDirectoryBuildStep(TEngine engine, bool continueOnError, string source, string target, bool deleteSource, string filePattern)
			: base(engine)
		{
			if (string.IsNullOrEmpty(source))
				throw new ArgumentException(Errors.NullOrEmpty, "source");

			if (string.IsNullOrEmpty(target))
				throw new ArgumentException(Errors.NullOrEmpty, "target");

			this.source = source;
			this.target = target;
			
			ContinueOnError = continueOnError;

			copier.DeleteSource = deleteSource;
			copier.FilePattern = filePattern;
		}
		#endregion

		#region Methods
		protected override void ExecuteInternal(BuildContext context)
		{
			context.Invoke(delegate()
			{
				context.TraceLine();
				context.TraceLine(ToString());
			});

			copier.CopyDirectory(source, target);
		}

		protected override void CancelInternal(BuildContext context)
		{
			copier.Stop();
		}

		public override string ToString()
		{
			StringBuilder text = new StringBuilder();

			text.Append((copier.DeepCopy) ? "Deep" : "Shallow");
			text.Append((copier.DeleteSource) ? " move" : " copy");

			if (!copier.CopyFiles)
				text.Append(" directories only from");
			else if (!string.IsNullOrEmpty(copier.FilePattern))
				text.Append(" " + copier.FilePattern + " in");

			text.Append(" \"" + source + "\" to \"" + target + "\".");

			return text.ToString();
		}
		#endregion
	}
}
